package com.example.student.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.student.config.BizException;
import com.example.student.entity.FileInfo;
import com.example.student.mapper.FileInfoMapper;
import com.example.student.service.FileInfoService;
import com.example.student.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {

    @Autowired
    private Environment environment;

    /**
     * 方法名 MethodName 批量保存
     */
    @Override
    public List<FileInfo> saveFiles(Map<String, MultipartFile> files) {
        // 创建文件信息容器,便于批量保存
        List<FileInfo> fileInfos = new ArrayList<>();

        for (MultipartFile file : files.values()) {
            // 处理并保存文件
            FileInfo fileInfo = getFileInfo(file);
            // 保存文件
            try {
                FileUtils.saveFile(file.getInputStream(),fileInfo.getFilePath());
            } catch (IOException e) {
                throw new BizException("保存文件到服务器时失败!");
            }
            // 添加到容器中
            fileInfos.add(fileInfo);
        }
        // 保存到数据库中
        saveBatch(fileInfos);
        return fileInfos;
    }


    @Override
    public FileInfo saveFile(byte[] bytes,String fileName)  {
        FileInfo fileInfo = getFileInfo(fileName, bytes.length);
        OutputStream os = null;
        try {
            String filePath = fileInfo.getFilePath();
            String filePath_p = filePath.substring(0,filePath.lastIndexOf("/"));
            if (!Files.exists(Paths.get(filePath_p))){
                Files.createDirectory(Paths.get(filePath_p));
            }
            os = new BufferedOutputStream(new FileOutputStream(filePath));
            os.write(bytes);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 保存到数据库中
        save(fileInfo);
        return fileInfo;
    }

    /**
     * 方法名 MethodName 获取文件存储文件信息及存储到本地
     */
    private FileInfo getFileInfo(MultipartFile file) {
        if (file.isEmpty()) {
            throw new BizException("文件不可为空!");
        }
        // 获取文件名
        String filename = file.getOriginalFilename();
        // 创建新文件名避免冲突,间戳 + 原文件名
        String newName = System.currentTimeMillis() + "_" + filename;
        // 截取出后缀名
        String suffixName = filename.substring(filename.lastIndexOf("."));
        // 获取文件大小
        long size = file.getSize();
        // 拼接要上传的文件夹
        String cdirPath = uploadDir() + dateDir();
        // 文件上传的全路径
        String filePath = cdirPath + newName;
        // 拼装文件信息对象返回
        FileInfo fileInfo = new FileInfo();
        fileInfo.setOriginalName(filename);
        fileInfo.setNewName(newName);
        fileInfo.setFileSize(size);
        fileInfo.setFileType(suffixName);
        fileInfo.setRelativePath(dateDir() + newName);
        fileInfo.setFilePath(filePath);
        return fileInfo;
    }

    /**
     * 方法名 MethodName 传入 文件名及大小 获取文件信息
     */
    private FileInfo getFileInfo(String fileName,long size) {
        // 创建新文件名避免冲突,间戳 + 原文件名
        String newName = System.currentTimeMillis() + "_" + fileName;
        // 截取出后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 拼接要上传的文件夹
        String cdirPath = uploadDir() + dateDir();
        // 文件上传的全路径
        String filePath = cdirPath + newName;
        // 拼装文件信息对象返回
        FileInfo fileInfo = new FileInfo();
        fileInfo.setOriginalName(fileName);
        fileInfo.setNewName(newName);
        fileInfo.setFileSize(size);
        fileInfo.setFileType(suffixName);
        fileInfo.setRelativePath(dateDir() + newName);
        fileInfo.setFilePath(filePath);
        return fileInfo;
    }


    private String uploadDir(){
        String basePath = null;
        try {
            // 获取配置文件配置的路径,如果没有设置 默认以类路径static作为基础路径
           return basePath = environment.getProperty("upload.dirPath", ResourceUtils.getFile(ResourceUtils.URL_PROTOCOL_WAR).toString() + "/upload");
        } catch (FileNotFoundException e) {
            throw new BizException(e.getMessage());
        }
    }

    private String dateDir(){
        // 获取当前时间,按月创建文件夹
        LocalDateTime time = LocalDateTime.now();
        int year = time.getYear();
        int value = time.getMonth().getValue();
        // 相对路径
        return "/" + String.valueOf(year) + String.valueOf(value) + "/";
    }
}

